#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#include <windows.h>  // 仅 Windows 需要，用于修复控制台乱码

void prn_info(int level, int actual_threads, int next_threads) {
    #pragma omp masked  // 确保每个并行区域仅主线程打印
    printf("LV%d: actual=%d, next=%d\n", level, actual_threads, next_threads);
}

int main() {
    SetConsoleOutputCP(CP_UTF8);  // 修复中文乱码（仅 Windows）
    omp_set_nested(1);            // 启用嵌套并行
    omp_set_dynamic(0);           // 禁用动态线程调整

    //-------------------------------------------
    // Case 1: 4 → 5 → 6
    //-------------------------------------------
    printf("\n===== Case 1 =====\n");
    #pragma omp parallel num_threads(4)  // 外层显式 4 线程
    {
        int outer_threads = omp_get_num_threads();
        prn_info(1, outer_threads, 5);  // 下一层设为 5 线程

        #pragma omp parallel num_threads(5)  // 内层显式 5 线程
        {
            int inner_threads = omp_get_num_threads();
            prn_info(2, inner_threads, 6);  // 下一层设为 6 线程

            #pragma omp parallel num_threads(6)  // 第三层显式 6 线程
            {
                int third_threads = omp_get_num_threads();
                prn_info(3, third_threads, 1);  // 无更深层级
            }
        }
    }

    //-------------------------------------------
    // Case 2: 8 → 5 → 6
    //-------------------------------------------
    printf("\n===== Case 2 =====\n");
    #pragma omp parallel num_threads(8)  // 外层显式 8 线程
    {
        int outer_threads = omp_get_num_threads();
        prn_info(1, outer_threads, 5);  // 下一层设为 5 线程

        #pragma omp parallel num_threads(5)  // 内层显式 5 线程
        {
            int inner_threads = omp_get_num_threads();
            prn_info(2, inner_threads, 6);  // 下一层设为 6 线程

            #pragma omp parallel num_threads(6)  // 第三层显式 6 线程
            {
                int third_threads = omp_get_num_threads();
                prn_info(3, third_threads, 1);  // 无更深层级
            }
        }
    }

    //-------------------------------------------
    // Case 3: 8 → 2 → 2
    //-------------------------------------------
    printf("\n===== Case 3 =====\n");
    #pragma omp parallel num_threads(8)  // 外层显式 8 线程
    {
        int outer_threads = omp_get_num_threads();
        prn_info(1, outer_threads, 2);  // 下一层设为 2 线程

        #pragma omp parallel num_threads(2)  // 内层显式 2 线程
        {
            int inner_threads = omp_get_num_threads();
            prn_info(2, inner_threads, 2);  // 下一层设为 2 线程

            #pragma omp parallel num_threads(2)  // 第三层显式 2 线程
            {
                int third_threads = omp_get_num_threads();
                prn_info(3, third_threads, 1);  // 无更深层级
            }
        }
    }

    return 0;
}